package top.jacktgq.concurrent_utils;

import top.jacktgq.utils.LogUtils;
import top.jacktgq.utils.Sleeper;

import java.util.concurrent.*;

/**
 * @Author CandyWall
 * @Date 2020/11/6--2:18
 * @Description 测试使用cyclicbarrier
 */
public class CyclicbarrierDemo {
    public static void main(String[] args) {
        demo1();
        //demo2();
    }

    //使用CountDownLatch完成等待任务1，2结束，然后做一些事情。然后将这一系列操作循环执行3遍
    //显然这样要完成这样的功能，CountDownLatch会被创建三遍
    private static void demo1() {
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 3; i++) {
            CountDownLatch latch = new CountDownLatch(2);
            threadPool.submit(() -> {
                LogUtils.log("CyclicbarrierDemo", "task1 start...");
                Sleeper.sleep(1);
                latch.countDown();
            });

            threadPool.submit(() -> {
                LogUtils.log("CyclicbarrierDemo", "task2 start...");
                Sleeper.sleep(2);
                latch.countDown();
            });

            try {
                //每一次循环，CountDownLatch都会阻塞在这里，
                //直到上面的任务都调用latch.countDown();才会继续往下执行
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            LogUtils.log("CyclicbarrierDemo", "task 1, task 2 finish...");
        }
        threadPool.shutdown();
    }

    //使用Cyclicbarrier优化demo1
    private static void demo2() {
        ExecutorService threadPool = Executors.newFixedThreadPool(2);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2, () -> {
            LogUtils.log("CyclicbarrierDemo", "task 1, task 2 finish...");
        });

        for (int i = 0; i < 3; i++) {
            threadPool.submit(() -> {
                LogUtils.log("CyclicbarrierDemo", "task1 start...");
                Sleeper.sleep(1);
                try {
                    cyclicBarrier.await();  //2-1=1
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

            threadPool.submit(() -> {
                LogUtils.log("CyclicbarrierDemo", "task2 start...");
                Sleeper.sleep(2);
                try {
                    cyclicBarrier.await();  //1-1=0
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }

        threadPool.shutdown();
    }
}
